package com.camel.chart.func;

import cn.hutool.core.util.ObjectUtil;
import com.camel.chart.MainApplication;
import com.camel.chart.call.DialogOkAfterCall;
import com.camel.chart.enums.MsgTypeEnum;
import com.camel.chart.utils.DialogUtil;
import com.camel.chart.utils.FileUtil;
import com.camel.chart.utils.MsgUtil;
import com.camel.chart.utils.SerializeUtil;
import com.camel.chart.utils.entity.*;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;

public class TcpServer implements Runnable{

    private int port;

    private MainApplication application;

    public static final String filePath = "D:/IamFxFiles";

    public MainApplication getApplication() {
        return application;
    }

    public void setApplication(MainApplication application) {
        this.application = application;
    }

    public static int size = 0;


    // 定义构造方法
    public TcpServer(int port, MainApplication application) {
        this.port = port;
        this.application = application;
    }
    @Override
    public void run() {
        while (true) {
            // 定义一个1024到字节数组，用于存放发送过来到数据
            byte[] data = new byte[5096];
            try (ServerSocket serverSocket = new ServerSocket(51818)) {
                Socket clientSocket = serverSocket.accept();
                String ip = clientSocket.getInetAddress().getHostAddress();
                InputStream inputStream = clientSocket.getInputStream();

                while (inputStream.read(data) > 0) {
                    Msg msg = Msg.deserialize(Arrays.copyOfRange(data, 0, 1000));
                    msg.setLeft(true);
                    if (msg.getType().equals(MsgTypeEnum.TYPE_FILE_MSG)) {
                        handleFile(msg, Arrays.copyOfRange(data, 1000, 5096));
                    } else {
                        msg.setDataTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                        msg.setOriginAddr(ip);
                        msg.setTargetAddr(ApplicationConfig.getInstance().getChartNetWorkInterface().getInetAddress());
                        msgHandler(ip, msg);
                    }
                }
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        }
    }


    /**
     * 消息回调
     */
    private void msgHandler(String ip, Msg msg) throws IOException {
        MsgTypeEnum type = msg.getType();

        if (MsgTypeEnum.TYPE_FILE_EOF.equals(type)) {
            MsgUtil.getInstance().updateMsgFileDownloadComplete(application, msg);
        }
        if (MsgTypeEnum.TYPE_TEXT_MSG.equals(type)) {
            if (!ChartHistory.getInstance().getMsges().containsKey(ip)) {
                ChartHistory.getInstance().getMsges().put(ip, new ArrayList<>());
            }
            msg.setLeft(true);
            Platform.runLater(() -> {
                ScrollPane scrollPane = this.getApplication().chartContent;
                VBox v = new VBox();
                HBox msgDateUI = MsgUtil.getInstance().createMsgDateUI(msg);
                if (ObjectUtil.isNotNull(msgDateUI)) {
                    msgDateUI.setPadding(new Insets(15, 15, 0, 15));
                    if (ObjectUtil.isEmpty(scrollPane.getContent())) {
                        v.getChildren().add(msgDateUI);
                        scrollPane.setContent(v);
                    } else {
                        VBox box = (VBox) scrollPane.getContent();
                        box.getChildren().add(msgDateUI);
                    }
                }

                HBox detailUI = MsgUtil.getInstance().createMsgDetailUI(msg);
                if (ObjectUtil.isNotNull(detailUI)) {
                    detailUI.setPadding(new Insets(3, 15, 0, 15));
                    if (ObjectUtil.isEmpty(scrollPane.getContent())) {
                        v.getChildren().add(detailUI);
                        scrollPane.setContent(v);
                    } else {
                        VBox box = (VBox) scrollPane.getContent();
                        box.getChildren().add(detailUI);
                    }
                }
            });

            ChartHistory.getInstance().getMsges().get(ip).add(msg);
            SerializeUtil.serializeObjAppendToFile(ip + ".txt", "history", msg);
        }

    }

    private void handleFile(Msg msg, byte[] bytes) throws IOException {
        //接收文件
        FileUtil.FileEntity fileEntity = (FileUtil.FileEntity) msg.getMsg();
        File file = new File(filePath, fileEntity.getFileName());
        if (!file.exists()) {
            // TODO 文件已存在
            file.createNewFile();
        }
        RandomAccessFile randomAccessFile = new RandomAccessFile(file.getPath(), "rw");
        FileChannel channel = null;
        try {
            channel = randomAccessFile.getChannel();
            channel.position(channel.size());
            int write = channel.write(ByteBuffer.wrap(bytes));
            System.out.println("---: " + write);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            channel.close();

        }
    }
}
